{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "# 习题：P134 7.2题"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "已知正例点$x_1=(1,2)^T,x_2=(2,3)^T,x_3=(3,3)^T$，负例点$x_4=(2,1)^T,x_5=(3,2)^T$，试求最大间隔分离平面和分类决策函数，并在图中挂出分离超平面、间隔边界及支持向量。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## sklearn.svm.SVC\n",
    "\n",
    "*(C=1.0, kernel='rbf', degree=3, gamma='auto', coef0=0.0, shrinking=True, probability=False,tol=0.001, cache_size=200, class_weight=None, verbose=False, max_iter=-1, decision_function_shape=None,random_state=None)*\n",
    "\n",
    "参数：\n",
    "\n",
    "- C：C-SVC的惩罚参数C，默认值是1.0\n",
    "\n",
    "C越大，相当于惩罚松弛变量，希望松弛变量接近0，即对误分类的惩罚增大，趋向于对训练集全分对的情况，这样对训练集测试时准确率很高，但泛化能力弱。C值小，对误分类的惩罚减小，允许容错，将他们当成噪声点，泛化能力较强。\n",
    "\n",
    "- kernel ：核函数，默认是rbf，可以是‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’ \n",
    "    \n",
    "    – 线性：u'v\n",
    "    \n",
    "    – 多项式：(gamma*u'*v + coef0)^degree\n",
    "\n",
    "    – RBF函数：exp(-gamma|u-v|^2)\n",
    "\n",
    "    – sigmoid：tanh(gamma*u'*v + coef0)\n",
    "\n",
    "\n",
    "- degree ：多项式poly函数的维度，默认是3，选择其他核函数时会被忽略。\n",
    "\n",
    "\n",
    "- gamma ： ‘rbf’,‘poly’ 和‘sigmoid’的核函数参数。默认是’auto’，则会选择1/n_features\n",
    "\n",
    "\n",
    "- coef0 ：核函数的常数项。对于‘poly’和 ‘sigmoid’有用。\n",
    "\n",
    "\n",
    "- probability ：是否采用概率估计？.默认为False\n",
    "\n",
    "\n",
    "- shrinking ：是否采用shrinking heuristic方法，默认为true\n",
    "\n",
    "\n",
    "- tol ：停止训练的误差值大小，默认为1e-3\n",
    "\n",
    "\n",
    "- cache_size ：核函数cache缓存大小，默认为200\n",
    "\n",
    "\n",
    "- class_weight ：类别的权重，字典形式传递。设置第几类的参数C为weight*C(C-SVC中的C)\n",
    "\n",
    "\n",
    "- verbose ：允许冗余输出？\n",
    "\n",
    "\n",
    "- max_iter ：最大迭代次数。-1为无限制。\n",
    "\n",
    "\n",
    "- decision_function_shape ：‘ovo’, ‘ovr’ or None, default=None3\n",
    "\n",
    "\n",
    "- random_state ：数据洗牌时的种子值，int值\n",
    "\n",
    "\n",
    "主要调节的参数有：C、kernel、degree、gamma、coef0。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.svm import SVC"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 加载数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = [[1, 2], [2, 3], [3, 3], [2, 1], [3, 2]]\n",
    "y = [1, 1, 1, -1, -1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练SVM模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "SVC(C=10000, cache_size=200, class_weight=None, coef0=0.0,\n",
       "  decision_function_shape='ovr', degree=3, gamma='auto_deprecated',\n",
       "  kernel='linear', max_iter=-1, probability=False, random_state=None,\n",
       "  shrinking=True, tol=0.001, verbose=False)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "clf = SVC(kernel='linear', C=10000)\n",
    "clf.fit(X, y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "w = [[-1.  2.]]\n",
      "b = [-2.]\n",
      "support vectors = [[3. 2.]\n",
      " [1. 2.]\n",
      " [3. 3.]]\n"
     ]
    }
   ],
   "source": [
    "print(\"w =\", clf.coef_)\n",
    "print(\"b =\", clf.intercept_)\n",
    "print(\"support vectors =\", clf.support_vectors_)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 最大间隔分离超平面\n",
    "$-x^{(1)}+2x^{(2)}-2=0$\n",
    "#### 分类决策函数\n",
    "$f(x)=sign(-x^{(1)}+2x^{(2)}-2)$\n",
    "#### 支持向量\n",
    "$x_1=(3,2),x_2=(1,2), x_3=(3,3)$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 绘制分离超平面、间隔边界、支持向量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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n14kt/fI1K6B92/79u3Y7Xa+/PJLrl+/TqNGjZg0aRLdunXD19fX6nhubd++fdSsWROAtWvXEhAQwLvvvkuXLl2s3wrQmVeA3LjoyF0lJSVljGwuX74spUuXlj59+siPP/6ob+JlU2JiokydOlUef/xxAcTX11f69esnmzdvtjqa27tx44ZMnDhRGjZsKIDs27dPRNLOeV5AR+7KVd3uRRITE0NgYCBbt26lePHiGW9Aqft35MgRxo4dy/jx4zl//jzVq1fns88+4+WXX6ZkyZJWx3Nr586d4+OPP2bChAlcunSJWrVqMXr06Iw3nl3uuevMK0BuXHTknv/88MMP0rFjRylQoIAYY6R9+/ayfPlyHaVnU0pKiixZskTatm0rxhjx8vKSzp07y6pVq7K15E6lnduTJ0+KiMj58+elaNGi0rVrV1m7dq1lz1t05K5cwYULFyhYsCBFixZl3759fP/99/z9739n0KBB2oskm86dO8eECROIiori6NGjlC9fnnfffZeBAwcSHBxsdTy3dubMmYytACtUqMCPP/5I6dKlOXXqFEWLFrU6nnOceQXIjYuO3D3bTz/9JH379pXChQvLJ598IiJpc+w3b960OJl7czgcsnHjRnnppZekYMGCAkjLli3lq6++0hVFOWDz5s3SvXv3jCWirVq1knnz5rnUX5foyF3lNRFh8uTJjBkzhtjYWPz8/Ojbty/PPPMMgO5Bmg3Xrl3jyy+/xG63s2PHDooVK8agQYMIDw+ndu3aVsdzawkJCXh7e1OkSBG2bNnCypUrefXVVwkPD89YCeOOTNoLQd4LDQ2V2NhYSx5b/ZaI8NNPP7F27VquXbtG6dKlef75552eNjlz5kzGm0qtWrXizJkzREZGai+SHLB79+6M7eoSEhKoV68ekZGRvPjii/j7+1sdz1Iiwrp169i4cSOJiYmULVuWF154gQoVKjj18zt37sRutzNt2jRGjBjB4MGDuXnzJg6HgyJFiuRy+vtnjNkiIqFZHacd9fO55cuXExoaSs+ePTl//jwFCxZk7969hIaG0r59e/bu3Zvpz6WkpDB//nyefvppKlasSFxcHACzZ89m165dREZGamG/T8nJycyePZuWLVtSp04doqOj6dChA99//z3btm0jLCws3xf22bNn89BDDxEREcGVK1fw8fFh27Zt1KlTh65du3L8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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 绘制数据点\n",
    "color_seq = ['red' if v==1 else 'blue' for v in y]\n",
    "plt.scatter([i[0] for i in X], [i[1] for i in X], c=color_seq)\n",
    "# 得到x轴的所有点\n",
    "xaxis = np.linspace(0, 3.5)\n",
    "w = clf.coef_[0]\n",
    "# 计算斜率\n",
    "a = -w[0] / w[1]\n",
    "# 得到分离超平面\n",
    "y_sep = a * xaxis - (clf.intercept_[0]) / w[1]\n",
    "# 下边界超平面\n",
    "b = clf.support_vectors_[0]\n",
    "yy_down = a * xaxis + (b[1] - a * b[0])\n",
    "# 上边界超平面\n",
    "b = clf.support_vectors_[-1]\n",
    "yy_up = a * xaxis + (b[1] - a * b[0])\n",
    "# 绘制超平面\n",
    "plt.plot(xaxis, y_sep, 'k-')\n",
    "plt.plot(xaxis, yy_down, 'k--')\n",
    "plt.plot(xaxis, yy_up, 'k--')\n",
    "# 绘制支持向量\n",
    "plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], s=150, facecolors='none', edgecolors='k')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.2"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": false,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
